package com.beerandjesus.sportofkings.handicapper.dao;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.springframework.core.io.ClassPathResource;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.List;

/**
 * Date: Sep 8, 2012
 * Time: 7:47:12 PM
 */
public class BaseSireDataFactory {

    private static final MathContext CTX_2 = new MathContext(2);
    private static final BigDecimal FIFTEEN_PERCENT = new BigDecimal(.15d, CTX_2);
    public static final MathContext CTX_3 = new MathContext(3);

    public BigDecimal getWinPercentage(BaseSireData d) {
        BigDecimal percentage;
        percentage = new BigDecimal(d.getWins())
                .divide(new BigDecimal(d.getStarts()), CTX_2);
        return percentage;
    }

    public List<BaseSireData> getBaseSireData(String[] baseDataFiles) throws IOException {
        BufferedReader r;
        List<BaseSireData> sires = new ArrayList<BaseSireData>();
        for (String res : baseDataFiles) {
            ClassPathResource cpr = new ClassPathResource(res);

            r = new BufferedReader(new InputStreamReader(cpr.getInputStream()));
            String line;
            try {
                while ((line = r.readLine()) != null) {
                    if (line.trim().equals("")) {
                        continue;
                    }
                    String[] elements = line.split("\t+");
                    if (elements.length != 4) {
                        throw new IOException("Unexpected format found in line: " + line);
                    }
                    String name = elements[0];
                    name = name.replaceAll("=", "");
                    name = name.replaceAll("\\([A-Z]+\\)", "");
                    final String theName = name.toUpperCase().trim();

                    String rating = elements[1].trim();
                    String s = elements[2].trim();
                    String w = elements[3].trim();

                    BaseSireData existing = (BaseSireData) CollectionUtils.find(sires, new Predicate() {
                        public boolean evaluate(Object object) {
                            BaseSireData d = (BaseSireData) object;
                            return (d.getName().equals(theName));
                        }
                    });
                    if (existing != null) {
                        // NOTE: we're ignoring updates to DPI (rating); any year's value is enough
                        int starts = new Integer(s) + existing.getStarts();
                        int wins = new Integer(w) + existing.getWins();
                        existing.setStarts(starts);
                        existing.setWins(wins);
                    } else {
                        BigDecimal dpi = new BigDecimal(rating, CTX_3);
                        sires.add(new BaseSireData(theName, new Integer(s), new Integer(w), dpi));
                    }
                }
            } finally {
                r.close();
            }
        }

        CollectionUtils.filter(sires, new Predicate() {
            public boolean evaluate(Object object) {
                BaseSireData o = (BaseSireData) object;
                if (o.getStarts() < 5) {
                    return false;
                }
                BigDecimal percentage;
                percentage = new BigDecimal(o.getWins())
                        .divide(new BigDecimal(o.getStarts()), CTX_2);
                return percentage.compareTo(FIFTEEN_PERCENT) >= 0;
            }
        });
        return sires;
    }


}
